package rbfnn;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import pso.Swarm;
import hybrid.MyFitnessFunction;
import hybrid.MyParticle;
import ls.LeastSquares;

public class Main {
	public static void main(String[] args) {
		int NumOfTrain, NumOfCluster, NumOfInput;
		String Train, Test;
		String delims = "[,]";
		Scanner in = new Scanner(System.in);
		List<Training> Trainings = new ArrayList<Training>();
		double[] output;
		
		System.out.println("Masukkan Jumlah Data Training: ");
		NumOfTrain = in.nextInt();
		output = new double[NumOfTrain];
		
		// System.out.println("Masukkan Jumlah Atribut: ");
		// NumOfInput = in.nextInt();
		
		System.out.println("Masukkan Data Training: ");
		for(int i = 0; i < NumOfTrain; i++)
		{
			Training tr;
			List<Double> Atr = new ArrayList<Double>();
			Train = in.next();
			String[] tokens = Train.split(delims);
			for(int j = 0; j < tokens.length - 1; j++)
			{
				Atr.add(Double.parseDouble(tokens[j]));
			}
			output[i] = Double.parseDouble(tokens[tokens.length - 1]); // for every tokens the length - 1 is the number of output training
			tr = new Training(Atr, output[i]);
			Trainings.add(tr);
		}
		
		// System.out.println("Masukkan Jumlah Clusters: ");
		// NumOfCluster = in.nextInt();
		
		Swarm swarm = new Swarm(Swarm.DEFAULT_NUMBER_OF_PARTICLES, new MyParticle(), new MyFitnessFunction(Trainings, 1, 2));
		swarm.setTrainings(Trainings);
		swarm.findMaxMinCenter();
		swarm.setInertia(0.95);
		swarm.setMaxPositionMod();
		swarm.setMinPositionMod();
		swarm.setMaxMinVelocity(0.1);
		int numberOfIterations = 100;

		// Optimize (and time it)
		for( int i = 0; i < numberOfIterations; i++ ){
			swarm.evolve();
			System.out.println("Iterasi ke - " + i + "\n");
		}

		// Print en results
		System.out.println();
		//System.out.println(swarm.toStringStats());
		//System.out.println("Particle "+ swarm.getBestParticleIndex());
		//System.out.println("//Particle "+ swarm.getParticle(swarm.getBestParticleIndex()).toString());
		//System.out.println(swarm.getBestPosition()[0]);
		System.out.println("Matrix Output Hidden Layer");
		RBF rbf = new RBF(Trainings, swarm.getBestPosition()); // swarm.getBestPosition() means the final center
		rbf.Training(20); //20 is the number of center clusters
		rbf.setWeight(LeastSquares.calcCoefficients(rbf.getBasFunc(), output));
		
		System.out.println();
		System.out.println("Weight untuk setiap basis function center: (Menggunakan Pseudoinverse)");
		for(int i = 0; i < LeastSquares.calcCoefficients(rbf.getBasFunc(), output).length; i++)
		{
			System.out.println("["+ (i+1) + "] " + Math.round( LeastSquares.calcCoefficients(rbf.getBasFunc(), output)[i] * 10000.0 ) / 10000.0 );
		}
		rbf.calculateRMSE(NumOfTrain, 20, output);
		System.out.println();
		//System.out.println("Masukkan Data Testing: ");
		while(true)
		{
			System.out.println("\nMasukkan Data Testing: ");
			Test = in.next();
			String[] tokens = Test.split(delims);
			double[] input = new double[tokens.length];
			for(int i = 0; i < input.length; i++)
			{
				input[i] = Double.parseDouble(tokens[i]);
			}
			System.out.println("Output Final: " + Math.round( rbf.CalculateOutput(input, 20) * 10000.0 ) / 10000.0);
		}
	}
}
